`timescale 1ns / 1ps
`include "AHB_slave.v"
module AHBslave2Reg#(
    parameter REG_BASE_ADDR = 32'h2000_0000
)(
    input clk,
    input rst_n,

    input[31:0]     HADDR,
    input           HWRITE,
    input[2:0]      HSIZE,
    input[2:0]      HBURST,
    input[1:0]      HTRANS,
    input[31:0]     HWDATA,
    output          HREADY,
    output[1:0]     HRESP,
    output[31:0]    HRDATA,

    inout[31:0]  io_reg0,
    inout[31:0]  io_reg1,
    inout[31:0]  io_reg2,
    inout[31:0]  io_reg3,
    inout[31:0]  io_reg4,
    inout[31:0]  io_reg5,
    output       r_or_w,
    output       refresh
);

reg r_refresh;
assign refresh =  r_refresh;

reg[31:0]  reg0;   //state;
reg[31:0]  reg1;   //row addr;
reg[31:0]  reg2;   //col addr;
reg[31:0]  reg3;   //RAM addr of read or write;
reg[31:0]  reg4;  
reg[31:0]  reg5;

wire[31:0]  addr;
wire[2:0]   burst;
wire[1:0]   trans;
wire[31:0]  wdata;
wire        write;
wire[2:0]   size;
wire[31:0]  rdata;
wire        ready;
wire[1:0]   resp;
wire        grant;
wire        busreq;

assign addr = HADDR;
assign write = HWRITE;
assign size = HSIZE;
assign burst = HBURST;
assign trans = HTRANS;
assign wdata = HWDATA;
assign HREADY = ready;
assign HRESP = resp;
assign HRDATA = rdata;

reg[1:0]   so_respon;
reg[31:0]  so_rdata;
reg        so_rdata_valid;
reg        so_wait_req_n;
wire[31:0] si_address;
wire       si_write;
wire       si_read;
wire[11:0] su_burst_count;
wire       si_brust_begin;
wire       su_lock;
wire[31:0] si_wdata;

assign io_reg0 = si_write ? reg0 : 32'hzzzz_zzzz;
assign io_reg1 = si_write ? reg1 : 32'hzzzz_zzzz;
assign io_reg2 = si_write ? reg2 : 32'hzzzz_zzzz;
assign io_reg3 = si_write ? reg3 : 32'hzzzz_zzzz;
assign io_reg4 = si_write ? reg4 : 32'hzzzz_zzzz;
assign io_reg5 = si_write ? reg5 : 32'hzzzz_zzzz;
assign r_or_w =  si_write ? 0 : 1;

AHB_slave u_AHB_slave(
	.clk                    (clk            ),
    .reset_n                (rst_n          ),

    .ahb_haddr              (addr           ),
    .ahb_hburst             (burst          ),
    .ahb_htrans             (trans          ),
    .ahb_hwdata             (wdata          ),
    .ahb_hwrite             (write          ),
    .ahb_hsize              (size           ),
    .ahb_hrdata             (rdata          ),
    .ahb_hready             (ready          ),
    .ahb_hresp              (resp           ),
    .ahb_hmastlock          (1'b1           ),
    .ahb_hprot              (4'h00          ),

    .avl_readdata           (so_rdata        ),
    .avl_readdatavalid      (so_rdata_valid  ),
    .avl_waitrequest_n      (so_wait_req_n   ),
    .avl_response           (so_respon       ),
    .avl_address            (si_address      ),
    .avl_write              (si_write        ),
    .avl_read               (si_read         ),
    .avl_burstcount         (su_burst_count  ),
    .avl_beginbursttransfer (si_brust_begin  ),
    .avl_lock               (su_lock         ),
    .avl_writedata          (si_wdata        )
);

always @(posedge clk or negedge rst_n) begin
    if (rst_n) begin
    end else begin
        so_wait_req_n <= 1;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (rst_n & si_read === 1) begin
        so_rdata_valid <= 1;
       case (si_address)
          REG_BASE_ADDR + 0 : so_rdata <= io_reg0;
          REG_BASE_ADDR + 1 : so_rdata <= io_reg1;
          REG_BASE_ADDR + 2 : so_rdata <= io_reg2;
          REG_BASE_ADDR + 3 : so_rdata <= io_reg3;
          REG_BASE_ADDR + 4 : so_rdata <= io_reg4;
          REG_BASE_ADDR + 5 : so_rdata <= io_reg5;
           default: so_rdata <= 32'hzzzz_zzzz;
       endcase 
    end else begin
        so_rdata_valid <= 0;
        so_respon <= `AHB_HRESP_OKAY;
    end
end

always @(negedge clk or negedge rst_n) begin
    if (rst_n) begin
        if (si_write === 1) begin
            r_refresh <= ~r_refresh;
            case (si_address)
                REG_BASE_ADDR + 0 : reg0 <= si_wdata;
                REG_BASE_ADDR + 1 : reg1 <= si_wdata;
                REG_BASE_ADDR + 2 : reg2 <= si_wdata;
                REG_BASE_ADDR + 3 : reg3 <= si_wdata;
                REG_BASE_ADDR + 4 : reg4 <= si_wdata;
                REG_BASE_ADDR + 5 : reg5 <= si_wdata;
            endcase 
        end else begin
            r_refresh <= r_refresh;
        end
    end else begin
        r_refresh <= 0;
    end
end

endmodule // AHBslave2Reg